package yxy.game.pm2.module.yiling;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.redisson.api.RMap;
import yxy.cherry.battle.module.Position;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.*;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.cherry.game.base.redis.RedisType;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.Format.FormatType;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.ServerBean;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.db.po.YiLingBattlePo;
import yxy.game.pm2.bean.module.RedisLock;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.message.BattleMessage;
import yxy.game.pm2.message.YiLingMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.battle.*;
import yxy.game.pm2.module.stat.StatHandle;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 夷陵之战
 */
public class YiLingBattleHandle extends BattleModuleHandle {

    final public static int battleExpireDay = 1;// 战斗数据过期时间（天）
    final public static int costForBuySweep = 30;// 购买一次扫荡花费的元宝
    final public static int maxChallengeTimes = 40;// 每天最大挑战次数


    protected String code() {
        return BattleType.YILING.name();
    }

    /**
     * 生成战斗缓存
     *
     * @param playerCode
     * @return
     */
    public BattleMessage.BattleResponse battleResponse(String playerCode) {
        YiLingBattleModule module = YiLingBattleModule.get(playerCode);
        //地图关卡
        int mapId = module.getMapId();
        BattleHandle battleHandle = new BattleHandle();
        //创建战斗的缓存
        BattleModule battleModule = BattleModule.create(playerCode);
        battleModule.setType(BattleType.YILING);
        battleModule.setCode(code());

        // 玩家的team
        TeamModule teamA = battleHandle.teamPlayer(playerCode, FormatType.普通);
        battleModule.setTeamA(teamA);

        //征战地图team
        TeamModule teamB = teamYiLing(mapId);
        battleModule.setTeamB(teamB);

        //设置当前地图的关卡以及奖励
        battleModule.setSettlement(SettlementYiLing.create(playerCode, mapId));

        //过期时间
        battleModule.set(battleExpireDay);

        return battleHandle.battleResponse(battleModule);
    }

    /**
     * 怪物的数据封装
     *
     * @param mapId
     * @return
     */
    private TeamModule teamYiLing(int mapId) {
        TeamModule team = new TeamModule();
        mapduplicate mapduplicate = DataCenter.getData(mapId, mapduplicate.class);
        ArrayList<FighterModule> fighterModules = getFighterModuleList(mapId);

        //战力
        long totalPower = 0;

        // 武将
        for (int i = 0; i < mapduplicate.getHeroid().length; i++) {
            Position position = Position.forValue(i + 1);
            int heroid = mapduplicate.getHeroid()[i];
            if (heroid == -1) continue;
            FighterModule fighterModule = fighterModules.get(i);
            team.addfighter(position, fighterModule);

            totalPower += fighterModule.getTotalPower();
        }
        // 神器
        WeaponModule weapon = WeaponModule.create(mapduplicate.getWeapondataid(), mapduplicate.getWeaponlv(), 0, 0, mapduplicate.getWeaponskilllv());
        team.setWeapon(weapon);

        // 信息
        team.setName(mapduplicate.getName());
        team.setHead(mapduplicate.getHeadid());
        team.setPower(totalPower);
        return team;
    }

    /**
     * 战斗记录封装
     *
     * @param playerCode
     * @param request
     * @return
     * @throws Exception
     */
    public BattleMessage.BattleExecuteResponse battleResponseExecute(String playerCode, BattleMessage.BattleExecuteRequest request) throws Exception {
        BattleModule module = BattleModule.get(playerCode, code());
        return new BattleHandle().battleResponseExecute(module, request);
    }

    /**
     * 处理下一个关卡
     */
    public void nextMap(String playerCode) {
        //todo 关卡处理
        RedisLock lock = YiLingBattleModule.lock(playerCode);
        try {
            if (lock.tryLock()) {
                YiLingBattleModule yiLingBattleModule = YiLingBattleModule.get(playerCode);
                int mapId = yiLingBattleModule.getMapId();
                mapduplicate mapduplicate = DataCenter.getData(mapId, mapduplicate.class);

                int nextId = mapduplicate.getNextid();
                if (DataCenter.getData(nextId, mapduplicate.class) != null) {
                    yiLingBattleModule.setMapId(nextId);
                }

                yiLingBattleModule.setMaxCustomsPass(yiLingBattleModule.getMaxCustomsPass() + 1); //每日挑战次数 + 1
                yiLingBattleModule.set();

                //排行榜更新
                RankYiLingBattle.getRank(playerCode).put(playerCode, mapId);
                StatHandle.stat_关卡统计(playerCode, CCReason.夷陵之战, mapId);

            }
        } catch (Exception e) {
        } finally {
            lock.unlock();
        }
    }


    /**
     * 夷陵之战首次通关奖励
     *
     * @param mapId
     * @return
     */
    static public Collection<Currency> mapReward(int mapId) {
        ArrayList<Currency> rewards = new ArrayList<>();
        // 固定奖励
        mapduplicate mapduplicate = DataCenter.getData(mapId, mapduplicate.class);
        if (mapduplicate != null) {
            rewards.addAll(Currency.create(mapduplicate.getRewardtype(), mapduplicate.getRewardid(), mapduplicate.getRewardnum()));
        }
        return rewards;
    }


    /**
     * 获取内存怪物战力属性
     */
    public ArrayList<FighterModule> getFighterModuleList(int mapid) {
        RMap<String, ArrayList<FighterModule>> rMap = RedisManager.getInstance().getConnection(RedisType.REDIS_DATA).client().getMap("INIT:mapduplicate");
        JSONArray arrary = (JSONArray) JSONArray.toJSON(rMap.get(String.valueOf(mapid)));
        ArrayList<FighterModule> fighterModules = JSON.parseObject(arrary.toString(), new TypeReference<ArrayList<FighterModule>>() {
        });
        return fighterModules;
    }

    /**
     * 通关奖励领取
     *
     * @param playerCode
     * @param id
     * @param response
     * @return
     */
    public Result levelReward(String playerCode, int id, YiLingMessage.YiLingBonusReceiveResponse.Builder response) {

        YiLingBattleModule module = YiLingBattleModule.get(playerCode);
        try {
            if (module.tryLock()) {
                if (id > module.getMapId()) {
                    return Result.YiLingBattleBonusCantRewarded;// 不能领取该奖励
                }

                for (int i = 0, size = module.getLevelReward().size(); i < size; i++) {
                    int levelRewardId = module.getLevelReward().get(i);
                    if (levelRewardId == id) {
                        return Result.YiLingBattleBonusRewarded;// 这个奖励已经领过
                    }
                }

                ArrayList<Integer> levelReward = module.getLevelReward();

                levelrewardduplicate _levelreward = levelReward == null || levelReward.size() == 0 ? DataCenter.getData(1, levelrewardduplicate.class) : DataCenter.getData(levelReward.size() + 1, levelrewardduplicate.class);

                Collection<Currency> rewards = Currency.create(_levelreward.getRewardtype(), _levelreward.getRewardid(), _levelreward.getRewardnum());
                new CurrencyHandle().addCurrency(playerCode, CCReason.夷陵之战, rewards);

                response.addAllRndRewards(new CurrencyHandle().packItems(rewards));
                module.getLevelReward().add(id);
                module.set();

                for (Integer levelRewardId : module.getLevelReward()) {
                    response.addIds(levelRewardId);
                }
                return Result.Success;
            }
        } catch (Exception e) {
        } finally {
            module.unlock();
        }
        return Result.DataError;

    }

    /**
     * 扫荡奖励
     *
     * @param mapId
     * @return
     */
    public static Collection<Currency> sweepRewards(int mapId) {
        ArrayList<Currency> rewards = new ArrayList<>();

        mapduplicate mapduplicate = DataCenter.getData(mapId, mapduplicate.class);
        if (mapduplicate == null) {
            return rewards;
        }

        rewards.addAll(Currency.create(mapduplicate.getSweeptype(), mapduplicate.getSweepid(), mapduplicate.getSweepnum()));

        return rewards;
    }


    /**
     * 购买花费
     *
     * @param num
     * @return
     */
    public static int buytimescost(int num) {
        return num * costForBuySweep;
    }


    /**
     * 获取每个关卡玩家信息
     * @param stageList
     * @param playerList
     * @param playerCode
     * @return
     */
    public static JSONArray getMapJson(List<Integer> stageList, List<YiLingBattlePo> playerList, String playerCode) {
        JSONArray mapJson = new JSONArray();
        for (Integer stage : stageList) {
            JSONObject jsonObject = new JSONObject();
            JSONArray players = new JSONArray();
            jsonObject.put("mapId", stage);
            for (YiLingBattlePo playerInfo : playerList) {
                if (playerInfo.getPlayerCode().equals(playerCode)) {
                    continue;
                }
                if (playerInfo.getMapId() == stage) {
                    players.add(playerInfo);
                }
            }
            jsonObject.put("heroList", players);
            mapJson.add(jsonObject);
        }
        return mapJson;
    }



    /**
     * 返回对应的地图信息  关卡id集合
     *
     * @param currentMap
     * @param playerCode
     * @return
     */
    public static List<Integer> getStageList(int currentMap, String playerCode) {
        RMap<String, ArrayList<Integer>> map = RedisManager.getInstance().getConnection(RedisType.REDIS_DATA).client().getMap("INIT:yilingmap");
        List<Integer> stageList = null;
        //没有传mapId  取玩家的当前关卡对应的地图界面id
        if (currentMap == 0) {
            YiLingBattleModule module = YiLingBattleModule.get(playerCode);
            //地图ID
            int mapId = module.getMapId() == 0 ? 1 : module.getMapId() % 30 > 0 ? (module.getMapId() / 30 + 1) : (module.getMapId() / 30);
            //mapduplicate data = DataCenter.getData(mapId, mapduplicate.class);
            stageList = map.get(String.valueOf(mapId));
        }

        //传进来有值，相当于翻页请求，重新把对应的地图信息返回
        if (currentMap != 0) {
            stageList = map.get(String.valueOf(currentMap));
        }

        return stageList;
    }

    public static int[] getStartAndEnd(List<Integer> stageList) {
        int[] ints = new int[2];
        ints[0] = Collections.min(stageList).intValue();
        ints[1] = Collections.max(stageList).intValue();
        return ints;
    }

    /**
     * 封装当前账号玩家信息
     * @param mapId
     * @param heroList
     * @param mapJson
     * @param yiLingBattlePo
     * @param player
     * @param serverBean
     * @param areaBean
     * @param module
     */
    public static String result(int mapId, JSONArray heroList, JSONArray mapJson, YiLingBattlePo yiLingBattlePo, PlayerBean player, ServerBean serverBean, AreaBean areaBean, YiLingBattleModule module){
        yiLingBattlePo.setMapId(mapId);
        yiLingBattlePo.setServerId(player.getServerId());
        yiLingBattlePo.setAreaId(serverBean.getAreaId());
        yiLingBattlePo.setGroupId(areaBean.getGroupId());
        yiLingBattlePo.setHead(player.getHead());
        yiLingBattlePo.setHeadFrame(player.getHeadframe());
        yiLingBattlePo.setLevel(player.getLevel());
        yiLingBattlePo.setPower(player.getPower());
        yiLingBattlePo.setPlayerCode(player.getCode());
        yiLingBattlePo.setUsername(player.getName());
        yiLingBattlePo.setUpdateTime(module.getTime().getMillis());
        heroList.add(yiLingBattlePo);
        return mapJson.toJSONString();
    }

    /**
     * 通关奖励领取
     * @param playerCode
     * @param id
     * @param response
     */
    public Result goThroughReward(String playerCode, int id, YiLingMessage.YiLingBonusReceiveResponse.Builder response) {

        RedisLock lock = YiLingBattleModule.lock(playerCode);
        try {
            if (lock.tryLock()) {
                YiLingBattleModule module = YiLingBattleModule.get(playerCode);

                for (int i = 0, size = module.getGoThroughReward().size(); i < size; i++) {
                    int levelRewardId = module.getGoThroughReward().get(i);
                    if (levelRewardId == id) {
                        // 已经领过
                        return Result.YiLingBattleBonusRewarded;// 通关奖励已经领过
                    }
                }

                levelrewardduplicate data = DataCenter.getData(id, levelrewardduplicate.class);
                if (data.getCondition() >= module.getMapId()) {
                    return Result.YiLingBattleBonusCantRewarded;// 通关奖励不能领取
                }

                Currency rewards = Currency.create(data.getRewardtype2(), data.getRewardid2(), data.getRewardnum2());
                new CurrencyHandle().addCurrency(playerCode, CCReason.夷陵之战, rewards);
                response.addAllRndRewards(new CurrencyHandle().packItems(rewards));

                module.getGoThroughReward().add(data.getId());
                module.set();

                for (Integer levelRewardId : module.getGoThroughReward()) {
                    response.addIds(levelRewardId);
                }

                return Result.Success;
            }
        } catch (Exception e) {
        } finally {
            lock.unlock();
        }

        return Result.DataError;
    }
}
